package edu.software.PBL_Management_System.util;

import lombok.extern.slf4j.Slf4j;
import lombok.extern.slf4j.XSlf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

// 验证码工具类
//TODO:后续如果添加了手机号验证，在这里添加验证方法
@Component
@Slf4j
public class VerificationCodeUtil {

    // 存储验证码的Map，key为邮箱，value为验证码和过期时间
    private static final Map<String, CodeInfo> codeMap = new ConcurrentHashMap<>();

    // 验证码有效期（秒）
    private static final int EXPIRE_TIME = 300;

    /**
     * 生成6位数字验证码
     * @return 验证码
     */
    public String generateCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 保存验证码
     * 1.系统当前时间 + 设置的过期时间（转换成毫秒） = 过期时间（毫秒）
     * 2.将验证码和过期时间封装到CodeInfo类中
     * 3.将过期时间与系统时间进行对比就能判断出验证码有没有过期
     * @param email 邮箱
     * @param code 验证码
     */
    public void saveCode(String email, String code) {
        long expireTime = System.currentTimeMillis() + EXPIRE_TIME * 1000L; //保存过期时间
        codeMap.put(email, new CodeInfo(code, expireTime));
    }

    /**
     * 验证验证码
     * @param email 邮箱
     * @param code 验证码
     * @return 是否验证成功
     */
    public boolean verifyCode(String email, String code) {
        log.info("开始验证验证码，邮箱：{}，输入的验证码：{}", email, code);

        // 打印当前存储的所有验证码信息（调试用）
        log.info("当前codeMap中的所有key：{}", codeMap.keySet());

        CodeInfo codeInfo = codeMap.get(email);
        if (codeInfo == null) {
            log.warn("验证码信息不存在，邮箱：{}", email);
            return false;
        }

        log.info("找到验证码信息，存储的验证码：{}，过期时间：{}",
                codeInfo.getCode(), new Date(codeInfo.getExpireTime()));

        // 验证码过期
        long currentTime = System.currentTimeMillis();
        if (currentTime > codeInfo.getExpireTime()) {
            log.warn("验证码已过期，当前时间：{}，过期时间：{}",
                    new Date(currentTime), new Date(codeInfo.getExpireTime()));
            codeMap.remove(email);
            return false;
        }

        // 验证码不匹配
        if (!codeInfo.getCode().equals(code)) {
            log.warn("验证码不匹配，存储的验证码：{}，输入的验证码：{}",
                    codeInfo.getCode(), code);
            return false;
        }

        log.info("验证码验证成功，邮箱：{}", email);
        // 验证成功后移除验证码
        codeMap.remove(email);
        return true;
    }
    /**
     * 获取验证码过期时间（秒）
     * @return 过期时间
     */
    public int getExpireTime() {
        return EXPIRE_TIME;
    }

    /**
     * 验证码信息类
     *  CodeInfo类用于封装验证码和过期时间，并提供获取验证码和过期时间的方法。
     */
    private static class CodeInfo {
        private final String code;
        private final long expireTime;

        public CodeInfo(String code, long expireTime) {
            this.code = code;
            this.expireTime = expireTime;
        }

        public String getCode() {
            return code;
        }

        public long getExpireTime() {
            return expireTime;
        }
    }
}